'    Copyright 2008 Jan Molnar <jan.molnar@abds.de>
'
'    This file is part of JCQ.

'    JCQ is free software: you can redistribute it and/or modify
'    it under the terms of the GNU General Public License as published by
'    the Free Software Foundation, either version 2 of the License, or
'    (at your option) any later version.

'    JCQ is distributed in the hope that it will be useful,
'    but WITHOUT ANY WARRANTY; without even the implied warranty of
'    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
'    GNU General Public License for more details.

'    You should have received a copy of the GNU General Public License
'    along with JCQ. If not, see <http://www.gnu.org/licenses/>.

Imports System.Collections.Specialized
Imports System.Collections.ObjectModel
Imports System.ComponentModel

Public Class NotifyingCollection(Of T)
    Inherits Collection(Of T)
    Implements Interfaces.INotifyingCollection(Of T)

    Public Sub New()

    End Sub

    Public Sub New(ByVal list As IList(Of T))
        MyBase.New(list)
    End Sub

    Public Sub Move(ByVal oldIndex As Integer, ByVal newIndex As Integer) Implements Interfaces.INotifyingCollection(Of T).Move
        Me.MoveItem(oldIndex, newIndex)
    End Sub

    Protected Overrides Sub InsertItem(ByVal index As Integer, ByVal item As T)
        MyBase.InsertItem(index, item)

        OnPropertyChanged("Count")
        OnPropertyChanged("Item[]")
        OnCollectionChanged(Specialized.NotifyCollectionChangedAction.Add, item, index)
    End Sub

    Protected Overridable Sub MoveItem(ByVal oldIndex As Integer, ByVal newIndex As Integer)
        Dim item As T = MyBase.Item(oldIndex)
        MyBase.RemoveItem(oldIndex)
        MyBase.InsertItem(newIndex, item)
        Me.OnPropertyChanged("Item[]")
        Me.OnCollectionChanged(Specialized.NotifyCollectionChangedAction.Move, item, newIndex, oldIndex)
    End Sub

    Protected Overrides Sub SetItem(ByVal index As Integer, ByVal item As T)
        MyBase.SetItem(index, item)
        Dim oldItem As T = MyBase.Item(index)

        OnPropertyChanged("Item[]")
        OnCollectionChanged(NotifyCollectionChangedAction.Replace, oldItem, item, index)
    End Sub

    Protected Overrides Sub RemoveItem(ByVal index As Integer)
        Dim item As T = MyBase.Item(index)

        MyBase.RemoveItem(index)

        OnPropertyChanged("Count")
        OnPropertyChanged("Item[]")
        OnCollectionChanged(NotifyCollectionChangedAction.Remove, item, index)
    End Sub

    Protected Overrides Sub ClearItems()
        MyBase.ClearItems()

        OnPropertyChanged("Count")
        OnPropertyChanged("Item[]")
        OnCollectionChanged(NotifyCollectionChangedAction.Reset)
    End Sub

    Protected Sub OnCollectionChanged(ByVal action As NotifyCollectionChangedAction)
        RaiseEvent CollectionChanged(Me, New NotifyCollectionChangedEventArgs(action))
    End Sub

    Protected Sub OnCollectionChanged(ByVal action As NotifyCollectionChangedAction, ByVal changedItem As T, ByVal index As Integer)
        RaiseEvent CollectionChanged(Me, New NotifyCollectionChangedEventArgs(action, changedItem, index))
    End Sub

    Protected Sub OnCollectionChanged(ByVal action As NotifyCollectionChangedAction, ByVal oldItem As T, ByVal newItem As T, ByVal index As Integer)
        RaiseEvent CollectionChanged(Me, New NotifyCollectionChangedEventArgs(action, newItem, oldItem, index))
    End Sub

    Private Sub OnCollectionChanged(ByVal action As NotifyCollectionChangedAction, ByVal item As Object, ByVal index As Integer, ByVal oldIndex As Integer)
        RaiseEvent CollectionChanged(Me, New NotifyCollectionChangedEventArgs(action, item, index, oldIndex))
    End Sub

    Protected Sub OnPropertyChanged(ByVal propertyName As String)
        RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs(propertyName))
    End Sub

    Public Event CollectionChanged(ByVal sender As Object, ByVal e As System.Collections.Specialized.NotifyCollectionChangedEventArgs) Implements System.Collections.Specialized.INotifyCollectionChanged.CollectionChanged

    Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
End Class